#include "stdafx.h"

#include "hwinenvironment.h"
#include "hwinexception.h"

#include <Knownfolders.h>
#include <Shlobj.h>
#include <stdarg.h>

#pragma comment(lib,"Secur32")

namespace harlinn
{
    namespace windows
    {
        HWIN_EXPORT Environment::Environment()
        {

        }

        HWIN_EXPORT String Environment::GetResourceString(const wchar_t* key, ...)
        {
            va_list args;
            va_start(args, key);
            
            wchar_t buffer[1024];

            std::string::size_type length = _vsnwprintf_s (buffer,1023, key, args );
            buffer[1023] = '\x0';
            String result(buffer,length);
            va_end(args);
            return result;
        }

        HWIN_EXPORT std::string Environment::GetResourceString(const char* key, ...)
        {
            va_list args;
            va_start(args, key);
            
            char buffer[1024];

            std::string::size_type length = vsnprintf_s (buffer,1023, key, args );
            buffer[1023] = '\x0';
            std::string result(buffer,length);
            va_end(args);
            return result;
        }

        HWIN_EXPORT String Environment::GetResourceString(const String& key, ...)
        {
            va_list args;
            va_start(args, key);
            
            wchar_t buffer[1024];

            std::string::size_type length = _vsnwprintf_s (buffer,1023, key.c_str(), args );
            buffer[1023] = '\x0';
            String result(buffer,length);
            va_end(args);
            return result;
        }


        HWIN_EXPORT String Environment::NewLine()
        {
            return String(L"\r\n",2);
        }

        HWIN_EXPORT String Environment::Expand(const String& s)
        {
            if(s)
            {
                auto length = ExpandEnvironmentStringsW(s.c_str(),nullptr,0);
                String result; 
                result.SetLength(result);
                ExpandEnvironmentStringsW(s.c_str(),result.c_str(),DWORD(length));
                return result;
            }
            return s;
        }


        // ---------------------------------------------------------------------
        // Environment::SystemParameters
        // ---------------------------------------------------------------------

        HWIN_EXPORT bool Environment::SystemParameters::ClearType()
        {
            BOOL result;
            if(SystemParametersInfoW(SPI_GETCLEARTYPE,0,&result,0) == FALSE)
            {
                ThrowLastOSError();
            }
            return result?true:false;
        }
        HWIN_EXPORT void Environment::SystemParameters::SetClearType(bool theValue, bool sendChange, bool updateProfile )
        {
            UINT flags = 0;
            if(sendChange)
            {
                flags |= SPIF_SENDCHANGE;
            }
            if(updateProfile)
            {
                flags |= SPIF_UPDATEINIFILE;
            }

            if(SystemParametersInfoW(SPI_SETCLEARTYPE,0,PVOID(theValue),flags) == FALSE)
            {
                ThrowLastOSError();
            }
        }

        HWIN_EXPORT String Environment::SystemParameters::DesktopWallpaper()
        {
            wchar_t buffer[MAX_PATH+1];
            if(SystemParametersInfoW(SPI_GETDESKWALLPAPER,MAX_PATH,buffer,0) == FALSE)
            {
                ThrowLastOSError();
            }
            return String(buffer);
        }
        HWIN_EXPORT void Environment::SystemParameters::SetDesktopWallpaper(const String& theValue, bool sendChange, bool updateProfile)
        {
            UINT flags = 0;
            if(sendChange)
            {
                flags |= SPIF_SENDCHANGE;
            }
            if(updateProfile)
            {
                flags |= SPIF_UPDATEINIFILE;
            }

            if(SystemParametersInfoW(SPI_SETDESKWALLPAPER,UINT(theValue.length()),PVOID(theValue.c_str()),flags) == FALSE)
            {
                ThrowLastOSError();
            }
        }


        HWIN_EXPORT bool Environment::SystemParameters::DropShadow()
        {
            BOOL result;
            if(SystemParametersInfoW(SPI_GETDROPSHADOW,0,&result,0) == FALSE)
            {
                ThrowLastOSError();
            }
            return result?true:false;
        }
        HWIN_EXPORT void Environment::SystemParameters::SetDropShadow(bool theValue, bool sendChange, bool updateProfile )
        {
            UINT flags = 0;
            if(sendChange)
            {
                flags |= SPIF_SENDCHANGE;
            }
            if(updateProfile)
            {
                flags |= SPIF_UPDATEINIFILE;
            }

            if(SystemParametersInfoW(SPI_SETDROPSHADOW,0,PVOID(theValue),flags) == FALSE)
            {
                ThrowLastOSError();
            }
        }


        HWIN_EXPORT bool Environment::SystemParameters::FlatMenu()
        {
            BOOL result;
            if(SystemParametersInfoW(SPI_GETFLATMENU,0,&result,0) == FALSE)
            {
                ThrowLastOSError();
            }
            return result?true:false;
        }
        HWIN_EXPORT void Environment::SystemParameters::SetFlatMenu(bool theValue, bool sendChange, bool updateProfile )
        {
            UINT flags = 0;
            if(sendChange)
            {
                flags |= SPIF_SENDCHANGE;
            }
            if(updateProfile)
            {
                flags |= SPIF_UPDATEINIFILE;
            }

            if(SystemParametersInfoW(SPI_SETFLATMENU,0,PVOID(theValue),flags) == FALSE)
            {
                ThrowLastOSError();
            }
        }

        HWIN_EXPORT bool Environment::SystemParameters::FontSmoothing()
        {
            BOOL result;
            if(SystemParametersInfoW(SPI_GETFONTSMOOTHING,0,&result,0) == FALSE)
            {
                ThrowLastOSError();
            }
            return result?true:false;
        }
        HWIN_EXPORT void Environment::SystemParameters::SetFontSmoothing(bool theValue, bool sendChange, bool updateProfile )
        {
            UINT flags = 0;
            if(sendChange)
            {
                flags |= SPIF_SENDCHANGE;
            }
            if(updateProfile)
            {
                flags |= SPIF_UPDATEINIFILE;
            }

            if(SystemParametersInfoW(SPI_SETFONTSMOOTHING,0,PVOID(theValue),flags) == FALSE)
            {
                ThrowLastOSError();
            }
        }

        HWIN_EXPORT UINT Environment::SystemParameters::FontSmoothingContrast()
        {
            UINT result;
            if(SystemParametersInfoW(SPI_GETFONTSMOOTHINGCONTRAST,0,&result,0) == FALSE)
            {
                ThrowLastOSError();
            }
            return result;
        }
        HWIN_EXPORT void Environment::SystemParameters::SetFontSmoothingContrast(UINT theValue, bool sendChange, bool updateProfile )
        {
            UINT flags = 0;
            if(sendChange)
            {
                flags |= SPIF_SENDCHANGE;
            }
            if(updateProfile)
            {
                flags |= SPIF_UPDATEINIFILE;
            }

            if(SystemParametersInfoW(SPI_SETFONTSMOOTHINGCONTRAST,0,PVOID(theValue),flags) == FALSE)
            {
                ThrowLastOSError();
            }
        }


        HWIN_EXPORT harlinn::windows::FontSmoothingOrientation Environment::SystemParameters::FontSmoothingOrientation()
        {
            UINT result;
            if(SystemParametersInfoW(SPI_GETFONTSMOOTHINGORIENTATION,0,&result,0) == FALSE)
            {
                ThrowLastOSError();
            }
            return harlinn::windows::FontSmoothingOrientation(result);
        }
        HWIN_EXPORT void Environment::SystemParameters::SetFontSmoothingOrientation(harlinn::windows::FontSmoothingOrientation theValue, bool sendChange, bool updateProfile )
        {
            UINT flags = 0;
            if(sendChange)
            {
                flags |= SPIF_SENDCHANGE;
            }
            if(updateProfile)
            {
                flags |= SPIF_UPDATEINIFILE;
            }

            if(SystemParametersInfoW(SPI_SETFONTSMOOTHINGCONTRAST,0,PVOID(theValue),flags) == FALSE)
            {
                ThrowLastOSError();
            }
        }

        HWIN_EXPORT std::shared_ptr<NONCLIENTMETRICS> Environment::SystemParameters::NonClientMetrics()
        {
            NONCLIENTMETRICS nonclientmetrics = {sizeof(NONCLIENTMETRICS),0,};

            if(SystemParametersInfoW(SPI_GETNONCLIENTMETRICS,sizeof(NONCLIENTMETRICS),&nonclientmetrics,0) == FALSE)
            {
                ThrowLastOSError();
            }
            auto result = std::make_shared<NONCLIENTMETRICS>(nonclientmetrics);
            return result;
        }





        // ---------------------------------------------------------------------
        // Environment::SystemMetrics
        // ---------------------------------------------------------------------
        HWIN_EXPORT int Environment::SystemMetrics::ScreenWidth() { return GetSystemMetrics(SM_CXSCREEN); }
        HWIN_EXPORT int Environment::SystemMetrics::ScreenHeight() { return GetSystemMetrics(SM_CYSCREEN); }
        HWIN_EXPORT SIZE Environment::SystemMetrics::ScreenSize()
        {
            SIZE result;
            result.cx = ScreenWidth();
            result.cy = ScreenHeight();
            return result;
        }
        HWIN_EXPORT int Environment::SystemMetrics::VerticalScrollBarWidth() { return GetSystemMetrics(SM_CXVSCROLL); }
        HWIN_EXPORT int Environment::SystemMetrics::HorizontalScrollBarHeight() { return GetSystemMetrics(SM_CYHSCROLL); }
        HWIN_EXPORT int Environment::SystemMetrics::CaptionHeight() { return GetSystemMetrics(SM_CYCAPTION); }
        HWIN_EXPORT int Environment::SystemMetrics::BorderWidth() { return GetSystemMetrics(SM_CXBORDER); }
        HWIN_EXPORT int Environment::SystemMetrics::BorderHeight() { return GetSystemMetrics(SM_CYBORDER); }
        HWIN_EXPORT int Environment::SystemMetrics::VerticalScrollBarThumbHeight() { return GetSystemMetrics(SM_CYVTHUMB); }
        HWIN_EXPORT int Environment::SystemMetrics::HorizontalScrollBarThumbWidth() { return GetSystemMetrics(SM_CXHTHUMB); }
        HWIN_EXPORT int Environment::SystemMetrics::IconWidth() { return GetSystemMetrics(SM_CXICON); }
        HWIN_EXPORT int Environment::SystemMetrics::IconHeight() { return GetSystemMetrics(SM_CYICON); }
        HWIN_EXPORT SIZE Environment::SystemMetrics::IconSize()
        {
            SIZE result;
            result.cx = IconWidth();
            result.cy = IconHeight();
            return result;
        }
        HWIN_EXPORT int Environment::SystemMetrics::CursorWidth() { return GetSystemMetrics(SM_CXCURSOR); }
        HWIN_EXPORT int Environment::SystemMetrics::CursorHeight() { return GetSystemMetrics(SM_CYCURSOR); }
        HWIN_EXPORT SIZE Environment::SystemMetrics::CursorSize()
        {
            SIZE result;
            result.cx = CursorWidth();
            result.cy = CursorHeight();
            return result;
        }
        HWIN_EXPORT int Environment::SystemMetrics::MenuBarHeight() { return GetSystemMetrics(SM_CYMENU); }
        HWIN_EXPORT int Environment::SystemMetrics::PrimaryDisplayWidth() { return GetSystemMetrics(SM_CXFULLSCREEN); }
        HWIN_EXPORT int Environment::SystemMetrics::PrimaryDisplayHeight() { return GetSystemMetrics(SM_CYFULLSCREEN); }
        HWIN_EXPORT SIZE Environment::SystemMetrics::PrimaryDisplaySize()
        {
            SIZE result;
            result.cx = PrimaryDisplayWidth();
            result.cy = PrimaryDisplayHeight();
            return result;
        }
        HWIN_EXPORT int Environment::SystemMetrics::KanjiWindowHeight() { return GetSystemMetrics(SM_CYKANJIWINDOW); }
        HWIN_EXPORT int Environment::SystemMetrics::MousePresent() { return GetSystemMetrics(SM_MOUSEPRESENT); }
        HWIN_EXPORT int Environment::SystemMetrics::VerticalScrollBarArrowHeight() { return GetSystemMetrics(SM_CYVSCROLL); }
        HWIN_EXPORT int Environment::SystemMetrics::HorizontalScrollBarArrowWidth() { return GetSystemMetrics(SM_CXHSCROLL); }
        HWIN_EXPORT int Environment::SystemMetrics::IsDebugVersion() { return GetSystemMetrics(SM_DEBUG); }
        HWIN_EXPORT int Environment::SystemMetrics::AreMouseButtonsSwapped() { return GetSystemMetrics(SM_SWAPBUTTON); }
        HWIN_EXPORT int Environment::SystemMetrics::MinimumWindowWidth() { return GetSystemMetrics(SM_CXMIN); }
        HWIN_EXPORT int Environment::SystemMetrics::MinimumWindowHeight() { return GetSystemMetrics(SM_CYMIN); }
        HWIN_EXPORT SIZE Environment::SystemMetrics::MinimumWindowSize()
        {
            SIZE result;
            result.cx = MinimumWindowWidth();
            result.cy = MinimumWindowHeight();
            return result;
        }
        HWIN_EXPORT int Environment::SystemMetrics::CaptionButtonWidth() { return GetSystemMetrics(SM_CXSIZE); }
        HWIN_EXPORT int Environment::SystemMetrics::CaptionButtonHeight() { return GetSystemMetrics(SM_CYSIZE); }
        HWIN_EXPORT SIZE Environment::SystemMetrics::CaptionButtonSize()
        {
            SIZE result;
            result.cx = CaptionButtonWidth();
            result.cy = CaptionButtonHeight();
            return result;
        }
        HWIN_EXPORT int Environment::SystemMetrics::SizeableBorderWidth() { return GetSystemMetrics(SM_CXFRAME); }
        HWIN_EXPORT int Environment::SystemMetrics::SizeableBorderHeight() { return GetSystemMetrics(SM_CYFRAME); }
        HWIN_EXPORT int Environment::SystemMetrics::MinimumWindowResizableWidth() { return GetSystemMetrics(SM_CXMINTRACK); }
        HWIN_EXPORT int Environment::SystemMetrics::MinimumWindowResizableHeight() { return GetSystemMetrics(SM_CYMINTRACK); }
        HWIN_EXPORT int Environment::SystemMetrics::DoubleClickAreaWidth() { return GetSystemMetrics(SM_CXDOUBLECLK); }
        HWIN_EXPORT int Environment::SystemMetrics::DoubleClickAreaHeight() { return GetSystemMetrics(SM_CYDOUBLECLK); }
        HWIN_EXPORT SIZE Environment::SystemMetrics::DoubleClickAreaSize()
        {
            SIZE result;
            result.cx = DoubleClickAreaWidth();
            result.cy = DoubleClickAreaHeight();
            return result;
        }
        HWIN_EXPORT int Environment::SystemMetrics::IconViewCellWidth() { return GetSystemMetrics(SM_CXICONSPACING); }
        HWIN_EXPORT int Environment::SystemMetrics::IconViewCellHeight() { return GetSystemMetrics(SM_CYICONSPACING); }
        HWIN_EXPORT SIZE Environment::SystemMetrics::IconViewCellSize()
        {
            SIZE result;
            result.cx = IconViewCellWidth();
            result.cy = IconViewCellHeight();
            return result;
        }
        HWIN_EXPORT int Environment::SystemMetrics::DropDownMenusAreRightAligned() { return GetSystemMetrics(SM_MENUDROPALIGNMENT); }
        HWIN_EXPORT int Environment::SystemMetrics::IsWindowsPenEnabled() { return GetSystemMetrics(SM_PENWINDOWS); }
        HWIN_EXPORT int Environment::SystemMetrics::DBCSEnabled() { return GetSystemMetrics(SM_DBCSENABLED); }
        HWIN_EXPORT int Environment::SystemMetrics::NumberOfMouseButtons() { return GetSystemMetrics(SM_CMOUSEBUTTONS); }
        HWIN_EXPORT int Environment::SystemMetrics::FixedBorderWidth() { return GetSystemMetrics(SM_CXFIXEDFRAME); }
        HWIN_EXPORT int Environment::SystemMetrics::FixedBorderHeight() { return GetSystemMetrics(SM_CYFIXEDFRAME); }

        HWIN_EXPORT int Environment::SystemMetrics::EdgeBorderWidth() { return GetSystemMetrics(SM_CXEDGE); }
        HWIN_EXPORT int Environment::SystemMetrics::EdgeBorderHeight() { return GetSystemMetrics(SM_CYEDGE); }
        HWIN_EXPORT int Environment::SystemMetrics::MinimizedWindowCellWidth() { return GetSystemMetrics(SM_CXMINSPACING); }
        HWIN_EXPORT int Environment::SystemMetrics::MinimizedWindowCellHeight() { return GetSystemMetrics(SM_CYMINSPACING); }
        HWIN_EXPORT int Environment::SystemMetrics::SmallIconWidth() { return GetSystemMetrics(SM_CXSMICON); }
        HWIN_EXPORT int Environment::SystemMetrics::SmallIconHeight() { return GetSystemMetrics(SM_CYSMICON); }
        HWIN_EXPORT SIZE Environment::SystemMetrics::SmallIconSize()
        {
            SIZE result;
            result.cx = SmallIconWidth();
            result.cy = SmallIconHeight();
            return result;
        }
        HWIN_EXPORT int Environment::SystemMetrics::SmallCaptionHeight() { return GetSystemMetrics(SM_CYSMCAPTION); }
        HWIN_EXPORT int Environment::SystemMetrics::SmallCaptionButtonWidth() { return GetSystemMetrics(SM_CXSMSIZE); }
        HWIN_EXPORT int Environment::SystemMetrics::SmallCaptionButtonHeight() { return GetSystemMetrics(SM_CYSMSIZE); }
        HWIN_EXPORT SIZE Environment::SystemMetrics::SmallCaptionButtonSize()
        {
            SIZE result;
            result.cx = SmallCaptionButtonWidth();
            result.cy = SmallCaptionButtonHeight();
            return result;
        }
        HWIN_EXPORT int Environment::SystemMetrics::MenuBarButtonWidth() { return GetSystemMetrics(SM_CXMENUSIZE); }
        HWIN_EXPORT int Environment::SystemMetrics::MenuBarButtonHeight() { return GetSystemMetrics(SM_CYMENUSIZE); }
        HWIN_EXPORT SIZE Environment::SystemMetrics::MenuBarButtonSize()
        {
            SIZE result;
            result.cx = MenuBarButtonWidth();
            result.cy = MenuBarButtonHeight();
            return result;
        }
        HWIN_EXPORT int Environment::SystemMetrics::MinimizedWindowsArragement() { return GetSystemMetrics(SM_ARRANGE); }
        HWIN_EXPORT int Environment::SystemMetrics::MinimizedWindowWidth() { return GetSystemMetrics(SM_CXMINIMIZED); }
        HWIN_EXPORT int Environment::SystemMetrics::MinimizedWindowHeight() { return GetSystemMetrics(SM_CYMINIMIZED); }
        HWIN_EXPORT int Environment::SystemMetrics::MaximumWindowResizableWidth() { return GetSystemMetrics(SM_CXMAXTRACK); }
        HWIN_EXPORT int Environment::SystemMetrics::MaximumWindowResizableHeight() { return GetSystemMetrics(SM_CYMAXTRACK); }
        HWIN_EXPORT int Environment::SystemMetrics::PrimaryDisplayMaximumWindowWidth() { return GetSystemMetrics(SM_CXMAXIMIZED); }
        HWIN_EXPORT int Environment::SystemMetrics::PrimaryDisplayMaximumWindowHeight() { return GetSystemMetrics(SM_CYMAXIMIZED); }
        HWIN_EXPORT int Environment::SystemMetrics::NetworkIsPresent() { return GetSystemMetrics(SM_NETWORK); }
        HWIN_EXPORT int Environment::SystemMetrics::CleanBoot() { return GetSystemMetrics(SM_CLEANBOOT); }
        HWIN_EXPORT int Environment::SystemMetrics::MinimumNoDragHorizontalMouseMovement() { return GetSystemMetrics(SM_CXDRAG); }
        HWIN_EXPORT int Environment::SystemMetrics::MinimumNoDragVerticalMouseMovement() { return GetSystemMetrics(SM_CYDRAG); }
        HWIN_EXPORT int Environment::SystemMetrics::ShowSounds() { return GetSystemMetrics(SM_SHOWSOUNDS); }
        HWIN_EXPORT int Environment::SystemMetrics::MenuCheckMarkWidth() { return GetSystemMetrics(SM_CXMENUCHECK); }
        HWIN_EXPORT int Environment::SystemMetrics::MenuCheckMarkHeight() { return GetSystemMetrics(SM_CYMENUCHECK); }
        HWIN_EXPORT SIZE Environment::SystemMetrics::MenuCheckMarkSize()
        {
            SIZE result;
            result.cx = MenuCheckMarkWidth();
            result.cy = MenuCheckMarkHeight();
            return result;
        }
        HWIN_EXPORT int Environment::SystemMetrics::SlowMachine() { return GetSystemMetrics(SM_SLOWMACHINE); }
        HWIN_EXPORT int Environment::SystemMetrics::MiddleEastEnabled() { return GetSystemMetrics(SM_MIDEASTENABLED); }
        HWIN_EXPORT int Environment::SystemMetrics::MouseWheelPresent() { return GetSystemMetrics(SM_MOUSEWHEELPRESENT); }
        HWIN_EXPORT int Environment::SystemMetrics::VirtualScreenXPosition() { return GetSystemMetrics(SM_XVIRTUALSCREEN); }
        HWIN_EXPORT int Environment::SystemMetrics::VirtualScreenYPosition() { return GetSystemMetrics(SM_YVIRTUALSCREEN); }
        HWIN_EXPORT POINT Environment::SystemMetrics::VirtualScreenPosition()
        {
            POINT result;
            result.x = VirtualScreenXPosition();
            result.y = VirtualScreenYPosition();
            return result;
        }
        HWIN_EXPORT int Environment::SystemMetrics::VirtualScreenWidth() { return GetSystemMetrics(SM_CXVIRTUALSCREEN); }
        HWIN_EXPORT int Environment::SystemMetrics::VirtualScreenHeight() { return GetSystemMetrics(SM_CYVIRTUALSCREEN); }
        HWIN_EXPORT SIZE Environment::SystemMetrics::VirtualScreenSize()
        {
            SIZE result;
            result.cx = VirtualScreenWidth();
            result.cy = VirtualScreenHeight();
            return result;
        }

        HWIN_EXPORT int Environment::SystemMetrics::NumberOfMonitors() { return GetSystemMetrics(SM_CMONITORS); }
        HWIN_EXPORT int Environment::SystemMetrics::MonitorsHasSameDisplayFormat() { return GetSystemMetrics(SM_SAMEDISPLAYFORMAT); }
        HWIN_EXPORT int Environment::SystemMetrics::InputMethodManagerEnabled() { return GetSystemMetrics(SM_IMMENABLED); }
        HWIN_EXPORT int Environment::SystemMetrics::FocusedBorderWidth() { return GetSystemMetrics(SM_CXFOCUSBORDER); }
        HWIN_EXPORT int Environment::SystemMetrics::FocusedBorderHeight() { return GetSystemMetrics(SM_CYFOCUSBORDER); }
        HWIN_EXPORT int Environment::SystemMetrics::TabletPC() { return GetSystemMetrics(SM_TABLETPC); }
        HWIN_EXPORT int Environment::SystemMetrics::MediaCenterPC() { return GetSystemMetrics(SM_MEDIACENTER); }
        HWIN_EXPORT int Environment::SystemMetrics::StarterEdition() { return GetSystemMetrics(SM_STARTER); }
        HWIN_EXPORT int Environment::SystemMetrics::WindowsServer2003R2BuildNumber() { return GetSystemMetrics(SM_SERVERR2); }
        HWIN_EXPORT int Environment::SystemMetrics::MouseHorizontalWheelPresent() { return GetSystemMetrics(SM_MOUSEHORIZONTALWHEELPRESENT); }
        HWIN_EXPORT int Environment::SystemMetrics::CaptionedWindowBorderPadding() { return GetSystemMetrics(SM_CXPADDEDBORDER); }
        HWIN_EXPORT int Environment::SystemMetrics::TabletPCInputTypeFlags() { return GetSystemMetrics(SM_DIGITIZER); }
        HWIN_EXPORT int Environment::SystemMetrics::MaximumTouches() { return GetSystemMetrics(SM_MAXIMUMTOUCHES); }
        HWIN_EXPORT int Environment::SystemMetrics::InTerminalServicesClientSession() { return GetSystemMetrics(SM_REMOTESESSION); }
        HWIN_EXPORT int Environment::SystemMetrics::ShuttingDown() { return GetSystemMetrics(SM_SHUTTINGDOWN); }
        HWIN_EXPORT int Environment::SystemMetrics::IsTerminalServerSessionRemoteControlled() { return GetSystemMetrics(SM_REMOTECONTROL); }
        HWIN_EXPORT int Environment::SystemMetrics::IsCaretBlinkingEnabled() { return GetSystemMetrics(SM_CARETBLINKINGENABLED); }
        HWIN_EXPORT int Environment::SystemMetrics::ConvertibleSlateMode() { return GetSystemMetrics(SM_CONVERTIBLESLATEMODE); }
        HWIN_EXPORT int Environment::SystemMetrics::IsSystemDocked() { return GetSystemMetrics(SM_SYSTEMDOCKED); }



        // ---------------------------------------------------------------------
        // Environment::ComputerName
        // ---------------------------------------------------------------------

        HWIN_EXPORT String Environment::ComputerName::QueryComputerName(COMPUTER_NAME_FORMAT format)
        {
            wchar_t buffer[512];
            DWORD bufferLength = sizeof(buffer)/sizeof(wchar_t);
            int length = GetComputerNameExW(format,buffer,&bufferLength);
            if(!length)
            {
                auto lastError = GetLastError();
                if(lastError == ERROR_MORE_DATA)
                {
                    String result(size_t(bufferLength),L'\x00');
                    length = GetComputerNameExW(format,const_cast<LPWSTR>(result.c_str()),&bufferLength);
                    if(!length)
                    {
                        ThrowLastOSError();
                    }
                    return result;
                }
                else
                {
                    ThrowLastOSError();
                }
            }
            String s(buffer,size_t(length));
            return s;
        }

        HWIN_EXPORT String Environment::ComputerName::DnsDomain()
        {
            return QueryComputerName(ComputerNameDnsDomain);
        }
        HWIN_EXPORT String Environment::ComputerName::DnsFullyQualified()
        {
            return QueryComputerName(ComputerNameDnsFullyQualified);
        }
        HWIN_EXPORT String Environment::ComputerName::DnsHostname()
        {
            return QueryComputerName(ComputerNameDnsHostname);
        }
        HWIN_EXPORT String Environment::ComputerName::NetBIOS()
        {
            return QueryComputerName(ComputerNameNetBIOS);
        }
        HWIN_EXPORT String Environment::ComputerName::PhysicalDnsDomain()
        {
            return QueryComputerName(ComputerNamePhysicalDnsDomain);
        }
        HWIN_EXPORT String Environment::ComputerName::PhysicalDnsFullyQualified()
        {
            return QueryComputerName(ComputerNamePhysicalDnsFullyQualified);
        }
        HWIN_EXPORT String Environment::ComputerName::PhysicalDnsHostname()
        {
            return QueryComputerName(ComputerNamePhysicalDnsHostname);
        }
        HWIN_EXPORT String Environment::ComputerName::PhysicalNetBIOS()
        {
            return QueryComputerName(ComputerNamePhysicalNetBIOS);
        }

        // ---------------------------------------------------------------------
        // Environment::ComputerName
        // ---------------------------------------------------------------------
        HWIN_EXPORT String Environment::UserName::QueryUserName(EXTENDED_NAME_FORMAT format)
        {
            wchar_t buffer[512];
            DWORD bufferLength = sizeof(buffer)/sizeof(wchar_t);
            int length = GetUserNameExW(format,buffer,&bufferLength);
            if(!length)
            {
                auto lastError = GetLastError();
                if(lastError == ERROR_MORE_DATA)
                {
                    String result(size_t(bufferLength),L'\x00');
                    length = GetUserNameExW(format,const_cast<LPWSTR>(result.c_str()),&bufferLength);
                    if(!length)
                    {
                        ThrowLastOSError();
                    }
                    return result;
                }
                else
                {
                    ThrowLastOSError();
                }
            }
            String s(buffer,size_t(length));
            return s;
        }

        HWIN_EXPORT String Environment::UserName::FullyQualifiedDN()
        {
            return QueryUserName(NameFullyQualifiedDN);
        }
        HWIN_EXPORT String Environment::UserName::SamCompatible()
        {
            return QueryUserName(NameSamCompatible);
        }
        HWIN_EXPORT String Environment::UserName::Display()
        {
            return QueryUserName(NameDisplay);
        }
        HWIN_EXPORT String Environment::UserName::UniqueId()
        {
            return QueryUserName(NameUniqueId);
        }
        HWIN_EXPORT String Environment::UserName::Canonical()
        {
            return QueryUserName(NameCanonical);
        }
        HWIN_EXPORT String Environment::UserName::UserPrincipal()
        {
            return QueryUserName(NameUserPrincipal);
        }
        HWIN_EXPORT String Environment::UserName::CanonicalEx()
        {
            return QueryUserName(NameCanonicalEx);
        }
        HWIN_EXPORT String Environment::UserName::ServicePrincipal()
        {
            return QueryUserName(NameServicePrincipal);
        }
        HWIN_EXPORT String Environment::UserName::DnsDomain()
        {
            return QueryUserName(NameDnsDomain);
        }
        HWIN_EXPORT String Environment::UserName::GivenName()
        {
            return QueryUserName(NameGivenName);
        }
        HWIN_EXPORT String Environment::UserName::Surname()
        {
            return QueryUserName(NameSurname);
        }

        // ---------------------------------------------------------------------
        // Environment::KnownFolder
        // ---------------------------------------------------------------------
        HWIN_EXPORT String Environment::KnownFolder::QueryKnownFolder(const GUID& folderId,KnownFolderFlags flags, HANDLE userToken)
        {
            wchar_t* buffer;
            DWORD theFlags = DWORD(flags);
            HRESULT hr = SHGetKnownFolderPath(folderId,KF_FLAG_NO_ALIAS|KF_FLAG_DONT_UNEXPAND,userToken,&buffer);
            CheckHRESULT(hr);
            String result(buffer);
            CoTaskMemFree(buffer);
            return result;
        }

        HWIN_EXPORT String Environment::KnownFolder::NetworkFolder(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_NetworkFolder,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::ComputerFolder(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_ComputerFolder,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::InternetFolder(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_InternetFolder,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::ControlPanelFolder(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_ControlPanelFolder,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::PrintersFolder(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_PrintersFolder,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::SyncManagerFolder(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_SyncManagerFolder,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::SyncSetupFolder(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_SyncSetupFolder,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::ConflictFolder(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_ConflictFolder,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::SyncResultsFolder(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_SyncResultsFolder,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::RecycleBinFolder(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_RecycleBinFolder,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::ConnectionsFolder(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_ConnectionsFolder,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Fonts(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Fonts,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Desktop(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Desktop,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Startup(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Startup,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Programs(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Programs,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::StartMenu(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_StartMenu,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Recent(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Recent,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::SendTo(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_SendTo,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Documents(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Documents,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Favorites(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Favorites,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::NetHood(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_NetHood,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::PrintHood(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_PrintHood,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Templates(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Templates,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::CommonStartup(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_CommonStartup,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::CommonPrograms(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_CommonPrograms,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::CommonStartMenu(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_CommonStartMenu,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::PublicDesktop(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_PublicDesktop,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::ProgramData(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_ProgramData,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::CommonTemplates(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_CommonTemplates,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::PublicDocuments(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_PublicDocuments,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::RoamingAppData(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_RoamingAppData,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::LocalAppData(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_LocalAppData,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::LocalAppDataLow(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_LocalAppDataLow,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::InternetCache(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_InternetCache,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Cookies(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Cookies,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::History(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_History,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::System(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_System,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::SystemX86(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_SystemX86,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Windows(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Windows,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Profile(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Profile,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Pictures(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Pictures,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::ProgramFilesX86(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_ProgramFilesX86,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::ProgramFilesCommonX86(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_ProgramFilesCommonX86,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::ProgramFilesX64(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_ProgramFilesX64,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::ProgramFilesCommonX64(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_ProgramFilesCommonX64,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::ProgramFiles(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_ProgramFiles,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::ProgramFilesCommon(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_ProgramFilesCommon,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::UserProgramFiles(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_UserProgramFiles,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::UserProgramFilesCommon(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_UserProgramFilesCommon,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::AdminTools(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_AdminTools,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::CommonAdminTools(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_CommonAdminTools,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Music(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Music,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Videos(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Videos,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Ringtones(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Ringtones,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::PublicPictures(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_PublicPictures,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::PublicMusic(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_PublicMusic,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::PublicVideos(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_PublicVideos,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::PublicRingtones(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_PublicRingtones,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::ResourceDir(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_ResourceDir,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::LocalizedResourcesDir(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_LocalizedResourcesDir,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::CommonOEMLinks(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_CommonOEMLinks,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::CDBurning(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_CDBurning,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::UserProfiles(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_UserProfiles,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Playlists(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Playlists,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::SamplePlaylists(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_SamplePlaylists,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::SampleMusic(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_SampleMusic,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::SamplePictures(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_SamplePictures,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::SampleVideos(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_SampleVideos,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::PhotoAlbums(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_PhotoAlbums,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Public(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Public,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::ChangeRemovePrograms(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_ChangeRemovePrograms,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::AppUpdates(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_AppUpdates,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::AddNewPrograms(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_AddNewPrograms,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Downloads(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Downloads,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::PublicDownloads(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_PublicDownloads,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::SavedSearches(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_SavedSearches,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::QuickLaunch(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_QuickLaunch,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Contacts(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Contacts,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::SidebarParts(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_SidebarParts,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::SidebarDefaultParts(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_SidebarDefaultParts,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::PublicGameTasks(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_PublicGameTasks,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::GameTasks(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_GameTasks,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::SavedGames(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_SavedGames,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Games(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Games,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::SEARCH_MAPI(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_SEARCH_MAPI,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::SEARCH_CSC(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_SEARCH_CSC,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Links(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Links,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::UsersFiles(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_UsersFiles,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::UsersLibraries(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_UsersLibraries,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::SearchHome(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_SearchHome,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::OriginalImages(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_OriginalImages,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::DocumentsLibrary(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_DocumentsLibrary,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::MusicLibrary(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_MusicLibrary,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::PicturesLibrary(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_PicturesLibrary,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::VideosLibrary(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_VideosLibrary,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::RecordedTVLibrary(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_RecordedTVLibrary,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::HomeGroup(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_HomeGroup,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::HomeGroupCurrentUser(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_HomeGroupCurrentUser,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::DeviceMetadataStore(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_DeviceMetadataStore,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Libraries(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Libraries,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::PublicLibraries(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_PublicLibraries,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::UserPinned(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_UserPinned,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::ImplicitAppShortcuts(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_ImplicitAppShortcuts,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::AccountPictures(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_AccountPictures,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::PublicUserTiles(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_PublicUserTiles,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::AppsFolder(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_AppsFolder,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::ApplicationShortcuts(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_ApplicationShortcuts,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::RoamingTiles(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_RoamingTiles,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::RoamedTileImages(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_RoamedTileImages,flags,userToken);
        }
        HWIN_EXPORT String Environment::KnownFolder::Screenshots(KnownFolderFlags flags, HANDLE userToken)
        {
            return QueryKnownFolder(FOLDERID_Screenshots,flags,userToken);
        }



    }
}